// Fill out your copyright notice in the Description page of Project Settings.


#include "MoveLine.h"
#include "PreOpenCVHeaders.h"
#include "opencv2/opencv.hpp"
#include "PostOpenCVHeaders.h"
#include "Components/Image.h"
#include "Components/Button.h"
#include "Blueprint/WidgetBlueprintLibrary.h"
#include "Components/CanvasPanelSlot.h"

void UMoveLine::NativeConstruct()
{
	Super::NativeConstruct();
	XLines.SetNum(2);
	YLines.SetNum(2);
}

void UMoveLine::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
	Super::NativeTick(MyGeometry, InDeltaTime);
	if (bDragging) {

		if (bXCoordiate) {
			for (FLine& line : YLines)
			{
				const FGeometry& ImgGeometry = Img->GetCachedGeometry();
				line.Start.X = 0;
				line.End.X = ImgGeometry.GetLocalSize().X;
			}
		}else
		{
			for (FLine& line : XLines)
			{
				const FGeometry& ImgGeometry = Img->GetCachedGeometry();
				const FGeometry& BtnGeometry = Btn->GetCachedGeometry();
				line.Start.Y = BtnGeometry.GetLocalSize().Y;
				line.End.Y = BtnGeometry.GetLocalSize().Y + ImgGeometry.GetLocalSize().Y;
			}
		}
	}
}

int32 UMoveLine::NativePaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect,
                             FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle,
                             bool bParentEnabled) const
{
	LayerId =  Super::NativePaint(Args, AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle,
	                          bParentEnabled);

	if (!IsValid(Img))
	{
		return LayerId;
	}

	FPaintContext Context(AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);

	if (bXCoordiate)
	{
		for (FLine line : XLines)
		{
			if (line.bValid) {
				UWidgetBlueprintLibrary::DrawLine(Context, line.Start, line.End, FLinearColor::Red, true, 2.0f);
			}
		}
	}
	else {
		for (FLine line : YLines)
		{
			if (line.bValid) {
				UWidgetBlueprintLibrary::DrawLine(Context, line.Start, line.End, FLinearColor::Red, true, 2.0f);
			}
		}
	}

	return LayerId + 1;
}

FReply UMoveLine::NativeOnMouseButtonDown(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
{
	if (InMouseEvent.GetEffectingButton() == EKeys::RightMouseButton)
	{
		if (bXCoordiate)
		{
			for (FLine& line : XLines)
			{
				if (!line.bValid)
				{
					FVector2D MousePosition = InGeometry.AbsoluteToLocal(InMouseEvent.GetScreenSpacePosition());
					line.bValid = true;
					line.Start.Y = MousePosition.Y;
					line.End.Y = MousePosition.Y;
					const FGeometry& ImgGeometry = Img->GetCachedGeometry();
					line.Start.X = 0;
					line.End.X = ImgGeometry.GetLocalSize().X;
					break;
				}
			}
		}
		else {
			for (FLine& line : YLines)
			{
				if (!line.bValid)
				{
					FVector2D MousePosition = InGeometry.AbsoluteToLocal(InMouseEvent.GetScreenSpacePosition());
					line.bValid = true;
					line.Start.X = MousePosition.X;
					line.End.X = MousePosition.X;
					const FGeometry& ImgGeometry = Img->GetCachedGeometry();
					const FGeometry& BtnGeometry = Btn->GetCachedGeometry();
					line.Start.Y = BtnGeometry.GetLocalSize().Y;
					line.End.Y = BtnGeometry.GetLocalSize().Y + ImgGeometry.GetLocalSize().Y;
					break;
				}
			}
		}

		return FReply::Handled().CaptureMouse(GetCachedWidget().ToSharedRef());
	}

	if (InMouseEvent.GetEffectingButton() == EKeys::LeftMouseButton)
	{
		FVector2D MousePosition = InGeometry.AbsoluteToLocal(InMouseEvent.GetScreenSpacePosition());

		if (bXCoordiate)
		{
			for (int8 i = 0; i < XLines.Num(); i++)
			{
				if (std::fabs(XLines[i].Start.Y - MousePosition.Y) < 10.0f)
				{
					SelectLine = i;
					bDragging = true;
					UE_LOG(LogTemp, Warning, TEXT("select line ：%d"), SelectLine);
					break;
				}
			}
		}
		else {
			for (int8 i = 0; i < YLines.Num(); i++)
			{
				if (std::fabs(YLines[i].Start.X - MousePosition.X) < 10.0f)
				{
					SelectLine = i;
					bDragging = true;
					UE_LOG(LogTemp, Warning, TEXT("select line ：%d"), SelectLine);
					break;
				}
			}
		}
	
		return FReply::Handled().CaptureMouse(GetCachedWidget().ToSharedRef());
	};
	
	return FReply::Unhandled();
}

FReply UMoveLine::NativeOnMouseMove(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
{
	if (bDragging) {
		FVector2D MousePosition = InGeometry.AbsoluteToLocal(InMouseEvent.GetScreenSpacePosition());

		if (bXCoordiate)
		{
			if (MousePosition.Y >= 0 && MousePosition.Y <= Img->GetCachedGeometry().GetLocalSize().Y) {
				if (SelectLine != -1)
				{
					XLines[SelectLine].Start.Y = MousePosition.Y;
					XLines[SelectLine].End.Y = MousePosition.Y;
				}
			}
		}
		else {

			if (MousePosition.X >= 0 && MousePosition.X <= InGeometry.GetLocalSize().X) {
				if (SelectLine != -1)
				{
					YLines[SelectLine].Start.X = MousePosition.X;
					YLines[SelectLine].End.X = MousePosition.X;
				}

				return FReply::Handled();
			}
		}
	}

	return FReply::Unhandled();
}

FReply UMoveLine::NativeOnMouseButtonUp(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent)
{
	if (InMouseEvent.GetEffectingButton() == EKeys::LeftMouseButton)
	{
		SelectLine = -1;
		bDragging = false;
		return FReply::Handled().ReleaseMouseCapture();
	}

	return FReply::Unhandled();
}
